package com.jielihaofeng.netty.bytebuf;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;

import static com.jielihaofeng.netty.bytebuf.TestByteBuf.log;
/**
 * @description ByteBuf 切片测试
 * @author Johnnie Wind
 * @date 2021/11/10 21:06
 */
public class TestSlice {

    public static void main(String[] args) {
        // 定义一个Bytebuf a,b,c,d,e,f,g,h,i,j
        ByteBuf buf = ByteBufAllocator.DEFAULT.buffer(10);
        buf.writeBytes(new byte[]{'a','b','c','d','e','f','i','j','k','l'});
        log(buf);

        // 切片，切片过程中并没有发生数据复制，效率高
        // 从第0个位置开始切片，a,b,c,d,e
        ByteBuf slice1 = buf.slice(0, 5);
        // 从第5个位置开始切片，f,i,j,k,l
        ByteBuf slice2 = buf.slice(5, 5);
        log(slice1);
        log(slice2);

        // 切片后的大小固定，不能再追加内容，如果执行，会报 IndexOutOfBoundsException 异常
        testOutOfBounds();
        // 切片后，切片拥有自己独立的读指针和写指针，ByteBuf的读指针移动不会影响切片读指针的移动
        testSelfPointer();
        // 切片后，对切片内容进行修改，原始的ByteBuf的值也发生了更改，因为它们底层都是共享同一块内存。
        testModify();
    }

    private static void testOutOfBounds() {
        // 切片后的大小固定，不能再追加内容，如果执行，会报 IndexOutOfBoundsException 异常
        // 定义一个Bytebuf a,b,c,d,e,f,g,h,i,j
        ByteBuf buf = ByteBufAllocator.DEFAULT.buffer(10);
        buf.writeBytes(new byte[]{'a','b','c','d','e','f','i','j','k','l'});
        log(buf);
        // 从0开始切片，5个字节：a,b,c,d,e
        ByteBuf slice = buf.slice(0, 5);
        // 切片追加内容，抛出异常
        slice.writeByte('x');
    }

    public static void testSelfPointer(){
        // 切片后，切片拥有自己独立的读指针和写指针，ByteBuf的读指针移动不会影响切片读指针的移动
        // 定义一个Bytebuf a,b,c,d,e,f,g,h,i,j
        ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(5);
        byteBuf.writeBytes(new byte[]{1,2,3,4,5});
        // 从0开始切片，5个字节：a,b,c,d,e
        ByteBuf slice = byteBuf.slice(0, 5);
        // 读取一个字节
        byteBuf.readByte();
        log(byteBuf);
        log(slice);
    }

    public static void testModify(){
        // 切片后，对切片内容进行修改，原始的ByteBuf的值也发生了更改，因为它们底层都是共享同一块内存。
        // 定义一个Bytebuf a,b,c,d,e,f,g,h,i,j
        ByteBuf buf = ByteBufAllocator.DEFAULT.buffer(10);
        buf.writeBytes(new byte[]{'a','b','c','d','e','f','i','j','k','l'});
        // 从0开始切片，5个字节：a,b,c,d,e
        ByteBuf slice = buf.slice(0, 5);
        // 修改第0个字节为 x
        slice.setByte(0,'x');
        log(buf);
        log(slice);
    }

}
